package course.webpart;

import course.ya.doc.from.code.model.ast.StatementTree;
import course.ya.doc.from.code.model.ast.StatementTreeBuilder;
import course.ya.doc.from.code.model.drawing.Draftsman;
import course.ya.doc.from.code.model.lexer.project.Keys;
import course.ya.doc.from.code.model.lexer.project.NodeTree;
import course.ya.doc.from.code.model.lexer.project.SyntaxTree;
import course.ya.doc.from.code.model.lexer.project.WrapperScanner;
import course.ya.doc.from.code.model.statements.IStatementFactory;
import course.ya.doc.from.code.model.statements.StateFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Map;

public class Facade {

    private WrapperScanner ws;
    private StatementTreeBuilder stb;
    private String className;
    private ArrayList<StatementTree> trees;
    private ArrayList<byte[]> images;

    public Facade(String sourceCode) {
        if (sourceCode != null) {
            ws = new WrapperScanner(sourceCode);
        }
        this.stb = null;
        this.className = "";
        this.trees = null;
        this.images = null;
    }

    public ArrayList<StatementTree> run() throws IOException {

        if (this.trees == null) {
            Map<Keys, SyntaxTree> mapSyntax = ws.scan();
            ArrayList treeList = new ArrayList(mapSyntax.values());
            ArrayList keyList = new ArrayList(mapSyntax.keySet());
            IStatementFactory factory;
            factory = StateFactory.getInstance();
            ListIterator<SyntaxTree> iter = treeList.listIterator();
            ListIterator<Keys> keyIter = keyList.listIterator();
            this.trees = new ArrayList<>();
            String treeName = "";

            while (iter.hasNext()) {
                SyntaxTree st = iter.next();
                NodeTree node = st.getRoot();
                treeName = keyIter.next().getFullName();
                stb = new StatementTreeBuilder(node, factory, treeName);
                StatementTree tr = stb.build();
                this.trees.add(tr);
            }
            this.className = treeName;
            return this.trees;
        }
        return this.trees;
    }

    public String getClassName() {

        try {
            this.run();
            return this.className;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public ArrayList<byte[]> getImages() {
        if (this.trees != null) {
            if (this.images == null) {
                return drawImages();
            } else {
                return this.images;
            }
        } else {
            try {
                this.run();
                return drawImages();
            } catch (IOException ex) {
                ex.printStackTrace();
            }

        }
        return null;
    }

    private ArrayList<byte[]> drawImages() {
        ListIterator<StatementTree> iter = this.trees.listIterator();
        this.images = new ArrayList<>();
        while (iter.hasNext()) {
            StatementTree tree = iter.next();
            Draftsman df = new Draftsman(tree, tree.getName());
            this.images.add(df.getByteArray());
        }
        return this.images;
    }
}
